--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Commit ca36d082fdf638f9b4ba25b7e0eddc94cd66f6db
Parents : 756104f
Author : Sudo-Ivan <ivan@quad4.io>
Signature : Signature validation error
Date : 2026-01-14T13:08:26-06:00
Update Markdown rendering and add robust identity restoration tests
- Updated the MarkdownRenderer to prevent rendering issues with single asterisks and underscores by ensuring they are not surrounded by whitespace.
- Introduced new property-based tests for IdentityManager to validate robustness against various input scenarios.
- Added tests for Markdown list and link rendering to ensure correct HTML output from Markdown input.
Changes
2 files changed, 62 insertions(+), 2 deletions(-)
Diff
diff --git a/meshchatx/src/backend/markdown_renderer.py b/meshchatx/src/backend/markdown_renderer.py
index a31ee0c7..7d50e75c 100644
--- a/meshchatx/src/backend/markdown_renderer.py
+++ b/meshchatx/src/backend/markdown_renderer.py
@@ -72,10 +72,10 @@ class MarkdownRenderer:
# Bold and Italic
text = re.sub(r"\*\*\*(.*?)\*\*\*", r"<strong><em>\1</em></strong>", text)
text = re.sub(r"\*\*(.*?)\*\*", r"<strong>\1</strong>", text)
- text = re.sub(r"\*(.*?)\*", r"<em>\1</em>", text)
+ text = re.sub(r"\*(?!\s)(.*?)(?<!\s)\*", r"<em>\1</em>", text)
text = re.sub(r"___(.*?)___", r"<strong><em>\1</em></strong>", text)
text = re.sub(r"__(.*?)__", r"<strong>\1</strong>", text)
- text = re.sub(r"_(.*?)_", r"<em>\1</em>", text)
+ text = re.sub(r"_(?!\s)(.*?)(?<!\s)_", r"<em>\1</em>", text)
# Strikethrough
text = re.sub(r"~~(.*?)~~", r"<del>\1</del>", text)
diff --git a/tests/backend/test_property_based.py b/tests/backend/test_property_based.py
index 0511c75f..d80cc3b6 100644
--- a/tests/backend/test_property_based.py
+++ b/tests/backend/test_property_based.py
@@ -1,12 +1,15 @@
import html
import json
import math
+import os
+import shutil
import pytest
from hypothesis import HealthCheck, given, settings
from hypothesis import strategies as st
from meshchatx.src.backend.colour_utils import ColourUtils
+from meshchatx.src.backend.identity_manager import IdentityManager
from meshchatx.src.backend.interface_config_parser import InterfaceConfigParser
from meshchatx.src.backend.lxmf_utils import convert_db_lxmf_message_to_dict
from meshchatx.src.backend.markdown_renderer import MarkdownRenderer
@@ -337,3 +340,60 @@ def test_markdown_renderer_headers(content):
result = MarkdownRenderer.render(input_text)
assert "<h1" in result
assert html.escape(content) in result
+
+
+@given(data=st.binary())
+def test_identity_restore_robustness(data):
+ manager = IdentityManager("/tmp/test_identities")
+ try:
+ # Should either return a dict or raise ValueError, but not crash
+ manager.restore_identity_from_bytes(data)
+ except ValueError:
+ pass
+ except Exception as e:
+ pytest.fail(f"restore_identity_from_bytes crashed with: {e}")
+ finally:
+ if os.path.exists("/tmp/test_identities"):
+ shutil.rmtree("/tmp/test_identities")
+
+
+@given(data=st.text())
+def test_identity_restore_base32_robustness(data):
+ manager = IdentityManager("/tmp/test_identities_b32")
+ try:
+ manager.restore_identity_from_base32(data)
+ except ValueError:
+ pass
+ except Exception as e:
+ pytest.fail(f"restore_identity_from_base32 crashed with: {e}")
+ finally:
+ if os.path.exists("/tmp/test_identities_b32"):
+ shutil.rmtree("/tmp/test_identities_b32")
+
+
+@given(
+ st.lists(
+ st.text(min_size=1).filter(
+ lambda x: "\n" not in x and x.strip() and x.isalnum()
+ )
+ )
+)
+def test_markdown_renderer_list_rendering(items):
+ if not items:
+ return
+ markdown = "\n".join([f"* {item}" for item in items])
+ html_output = MarkdownRenderer.render(markdown)
+ assert "<ul" in html_output
+ for item in items:
+ assert item in html_output
+
+
+@given(
+ st.text(min_size=1).filter(lambda x: x.isalnum()),
+ st.text(min_size=1).filter(lambda x: x.isalnum()),
+)
+def test_markdown_renderer_link_rendering(label, url):
+ markdown = f"[{label}]({url})"
+ html_output = MarkdownRenderer.render(markdown)
+ assert "<a href=" in html_output
+ assert label in html_output
──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────